package com.qianji.petmall.product.config;

import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author liang zai
 * @date 2022/2/17 11:28
 * @description
 */

//设置缓存保存的数据为json数据，之前为jdk
//配置文件中的配置没有用上
/**
 *   1、原来的配置文件绑定的配置类是这样子的
 *   @ConfigurationProperties(prefix = "spring.cache")
 *   public class CacheProperties
 *   2、我们要让他生效需要添加以下注解
 *   @EnableConfigurationProperties(CacheProperties.class)
 *
 *   @Cacheable: 触发缓存填充（开启缓存）。
 *   @CacheEvict: 触发缓存回收。
 *   @CachePut: 在不干扰方法执行的情况下更新缓存。
 *   @Caching: 将应用于一个方法的多个缓存操作重新分组。
 *   @CacheConfig: 在类级别共享一些与缓存相关的公共设置。
 *   1、读模式
 *   缓存穿透：spring.cache.redis.cache-null-values=true
 *   缓存击穿：大并发进来同时查询一个数据正好过期，解决，加锁：sync = true
 *   缓存雪崩：大量的key同时过期，解决：过期时间加随机性。
 *   2、写模式
 *   读写加锁
 *   引入Canal，感知到数据库更新去更新数据库
 *
 *
 */
@Configuration
@EnableCaching
public class MyCacheConfig {

    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //key的序列化 string
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        //value的序列化  json
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        //将配置文件中所有的配置都生效
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }

}
